//{{{

// Default values for some sGTD-specific tiddler fields
var default_values = new Array();
default_values["priority"]=100;
default_values["progress"]=0;
default_values["status"]="TBD";
default_values["project"]="LIFE";

// Test if the tiddler is a project
function isProject(tid) { if(!tid.isTagged("GTD")&&!tid.isTagged("NOT_TASK")&&!tid.isTagged("GTD_REFERENCE")&&!tid.isTagged("GTD_INCUBATE")&&!tid.isTagged("GTD_TRASH")&&!tid.isTagged("GTD_DONE")&&!tid.isTagged("systemConfig")) {
   // alert("checking project");
    return (tid.text.search(/\[\[[^\[\]]*\]\]/i)!=-1) || (tid.text.search("<<itemList")!=-1);
  }
 // alert("returning false");
  return false;
}

// Test if the tiddler is a task
function isTask(tid) {  if(!tid.isTagged("GTD")&&!tid.isTagged("NOT_TASK")&&!tid.isTagged("GTD_REFERENCE")&&!tid.isTagged("GTD_INCUBATE")&&!tid.isTagged("GTD_TRASH")&&!tid.isTagged("GTD_DONE")&&!tid.isTagged("systemConfig")) {
  //  alert("checking task");
    return (tid.text.search(/\[\[[^\[\]]*\]\]/i)==-1) && (tid.text.search("<<itemList")==-1);
  }
//  alert("returning false");
  return false;
}

// Returns a list of all the projects
function getProjects() {
  var tids=[];
  store.forEachTiddler(function(title,tiddler) {
    if(isProject(tiddler)) tids.push(tiddler);
  });
  return tids;
}

// Returns a list of all the tasks
function getTasks() {
  var tids=[];
  store.forEachTiddler(function(title,tiddler) {
    if(isTask(tiddler)) tids.push(tiddler);
  });
  return tids;
}

// Gets the property of an item by name and type
function getProp(tid,prop,type) {
  var p=(tid.fields[prop]==null || tid==null)?default_values[prop]:tid.fields[prop];
  
  if(type=="string") return p;
  if(type=="int") return parseInt(p,10);
  if(type=="float") return parseFloat(p);  
}

// Returns a list of sub-items of a project
function getProjectItems(tid) {
  var regex=/\[\[([^\[\]]*)\]\]/g;
  var nl_regex=/([^|]*)\|([^|]*)/g;
  //var tasks=tid.text.match(/\[\[([^\[\]]*)\]\]/g);
  var names_list = new Array();
  var tid_list = new Array();
  var name = regex.exec(tid.text);
  var name_to_push="";
  var atid;
  while(name!=null) {
    if(name[1].search(nl_regex)!=-1) {
      nl_regex.compile(nl_regex);
      //alert("Got one!!! "+name[1]);
      var nl=nl_regex.exec(name[1]);
      //alert(nl.toString());
      name_to_push=nl[2];
    } else
    { name_to_push=name[1]; }
    names_list.push(name_to_push);
    name = regex.exec(tid.text);
  }
  //alert(names_list.toString());
  for(var i=0;i<names_list.length;i++) {
    atid=store.getTiddler(names_list[i]);
    if(atid!=null) tid_list.push(atid);
  }
  return tid_list;  
}

// Returns the parent project with the highest priority
function getParentProject(tid) {
  var refs = store.getReferringTiddlers(tid.title);
  if(refs==null && tid.fields["project"]==null) return store.getTiddler("LIFE");
  if(refs.length==0 && tid.fields["project"]==null) return store.getTiddler("LIFE");
  if(tid.fields["project"]!=null) return store.getTiddler(tid.fields["project"]);
  if(refs.length>1) {
    var compf = function(a,b) {
      var pa=getProp(a,"prio","int");
      var pb=getProp(b,"prio","int");
      return pa-pb;
    };
    refs.sort(compf);
  }
  return refs[refs.length-1];
}

// Returns a list of all the parent projects
function getParentProjects(tid) {
  return store.getReferringTiddlers(tid.title);
}

// Calculate item progress
function getItemProgress(item) {
	if(isTask(item)) return getProp(item,"progress","float");
	var subitems = getProjectItems(item);
	var sum=0;
	for(var i=0;i<subitems.length;i++) {
		sum+=getProp(subitems[i],"progress","float") * getProp(subitems[i],"priority","float");
	}
        // alert("sum="+sum.toString()+" length="+subitems.length.toString());
        if( (sum==0 && subitems.length==0) || (subitems.length==0) ) return 0;
	return sum/subitems.length;
}

// Display tasks sorted by a function
function displayTasksList(sf,tasks) {
	if(tasks==undefined) var tasks = getTasks();
	tasks.sort(sf);
	var out="|!Task|!Parent project|!Priority|!Progress|!Status|\n";
	for(var i=0;i<tasks.length;i++) {
		out+="|[["+tasks[i].title+"]]|[["
			+getParentProject(tasks[i]).title+"]]|"
			+getProp(tasks[i],"priority","string")+"|"
			+getItemProgress(tasks[i]).toString()+"|"
			+getProp(tasks[i],"status","string")+"|\n";
	}
	return out;
}

// Display projects sorted by a function
function displayProjectsList(sf,projects) {
	if(projects==undefined) projects = getProjects();
	projects.sort(sf);
	var out="|!Project|!Parent project|!Priority|!Progress|!Status|\n";
	for(var i=0;i<projects.length;i++) {
		out+="|[["+projects[i].title+"]]|[["
			+getParentProject(projects[i]).title+"]]|"
			+getProp(projects[i],"priority","string")+"|"
			+getItemProgress(projects[i]).toString()+"|"
			+getProp(projects[i],"status","string")+"|\n";
	}
	return out;
}

// Macro to create list of items(not recommended)
config.macros.itemList = {};
config.macros.itemList.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 var out="";
 var nl_regex=/([^|]*)\|([^|]*)/g;
 var name="";
 out+="|!Item name|!Description|!Delete|\n";
 for(var i=0;i<params.length;i+=2) {  
  if(params[i].search(nl_regex)!=-1) {
      nl_regex.compile(nl_regex);
      var nl=nl_regex.exec(name[1]);
      name=nl[2];
  } else { name=params[i];}
  if(!store.tiddlerExists(name)) { 
    var tid=store.createTiddler(name);
    tid.creator=config.options.txtUserName;
    tid.fields["project"]=tiddler.title;
    store.setTiddlerTag(name,true,"GTD_STUFF");    
  }
  var div_id=tiddler+"_"+name+"_"+i.toString();
  var del_html="<html><input type=button value=Delete onclick=\"store.fetchTiddler('"+name+"').tags.length=0;store.setTiddlerTag('"+name+"',true,'GTD_TRASH');document.getElementById('"+div_id+"').innerHTML=removed\"><div id='"+div_id+"'></div></html>";
  if(!store.getTiddler(name).isTagged("GTD_TRASH")) {
    out+="|[["+params[i]+"]]|"+params[i+1]+"|"+del_html+"|\n";
  }
 }
 wikify(out,place);
};

// Marco to set property fields
config.macros.setpr = {};
config.macros.setpr.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 var pname=params.length>0?params[0]:"prio";
 var pvalue=params.length>0?params[1]:"0";
 tiddler.fields[pname]=pvalue;
 wikify("%''"+pname+"''"+" = //"+pvalue+"//",place);
};

// sGTD item template
merge(config.views.editor,{
	tagPrompt: "Type tags separated with spaces, [[use double square brackets]] if necessary, or add existing",
	defaultText: "Type the text for '%0'\n\n"+
	"<<setpr priority 100>>\n"+
	"<<setpr progress 0>>\n"+
	"<<setpr status TBD>>\n"
}
);

//}}}
